package opt_gorm

import (
	"encoding/json"
	"fmt"
	"gorm.io/driver/postgres"
	"gorm.io/gorm"
	"gorm.io/gorm/schema"
	"sync"
	"time"
)

type Blade_region struct {
	Code string `gorm:"primary_key"`
	ParentCode,
	Ancestors,
	Name,
	ProvinceCode,
	ProvinceName,
	CityCode,
	CityName,
	DistrictCode,
	DistrictName,
	TownCode,
	TownName,
	VillageCode,
	VillageName string
	Level  int64
	Sort   int64
	Remark string
}

// 默认绑定表名blade_log_apis
type Blade_log_api struct {
	ID int64 `gorm:"primary_key"`
	Tenant_id,
	Service_id,
	Server_host,
	Server_ip,
	Env,
	Type,
	Title,
	Method,
	Request_uri,
	User_agent,
	Remote_ip,
	Method_class,
	Method_name,
	Params string
	Time        string
	Create_by   string
	Create_time time.Time
}

var postgres_db *gorm.DB

func (api Blade_log_api) TableName() string {
	return "ggzb.blade_log_api"
}

func init() {
	dsn := "host=43.139.126.192 user=root password=10086 dbname=initdb port=7432 sslmode=disable TimeZone=Asia/Shanghai"
	db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{
		CreateBatchSize: 1000,
		NamingStrategy: schema.NamingStrategy{
			TablePrefix:   "ggzb.",
			SingularTable: true,
		},
		//  all Field Module match
		QueryFields: true,
		// SQL Compile Cache
		PrepareStmt: true,
	})

	postgres_db = db
	if err != nil {
		fmt.Println("err gorm open postgres is exception", err)
	}

}

var wg sync.WaitGroup

func opt_gorm_postgres() {
	// Blade_region 与 DDL同步
	// postgres_db.AutoMigrate(&Blade_region{}, &Blade_log_api{})
	wg.Add(2)

	var insert []Blade_log_api

	go func() {
		for i := 0; i <= 5000000; i++ {
			insert = append(insert, Blade_log_api{
				int64(1349540347359580162 + i),
				fmt.Sprintf("000%d", i),
				"blade-api",
				fmt.Sprintf("127.0.0.%d", i),
				fmt.Sprintf("127.0.0.%d", i+2),
				"dev",
				"2",
				"Title",
				"GET/POST",
				"/v1",
				"windows，Agent",
				"127.0.0.1",
				"User.class",
				"getUser",
				`{user}`,
				time.Now().Format("2006-01-02 15:04:05"),
				fmt.Sprintf("system%d", i),
				time.Now(),
			})
		}
		defer wg.Done()
	}()

	var insert2 []Blade_log_api
	go func() {
		for i := 0; i <= 5000000; i++ {
			insert2 = append(insert2, Blade_log_api{
				int64(3495434162 + i),
				fmt.Sprintf("000%d", i),
				"blade-api",
				fmt.Sprintf("127.0.0.%d", i),
				fmt.Sprintf("127.0.0.%d", i+2),
				"dev",
				"2",
				"Title",
				"GET/POST",
				"/v1",
				"windows，Agent",
				"127.0.0.1",
				"User.class",
				"getUser",
				`{user}`,
				time.Now().Format("2006-01-02 15:04:05"),
				fmt.Sprintf("system%d", i),
				time.Now(),
			})
		}
		defer wg.Done()
	}()

	wg.Wait()

	wg.Add(2)

	go func(data *[]Blade_log_api) {
		defer wg.Done()
		tx := postgres_db.Create(data)
		affected := tx.RowsAffected
		fmt.Println("insert log_api rows", affected)
	}(&insert)

	go func(data *[]Blade_log_api) {
		defer wg.Done()
		tx := postgres_db.Create(data)
		affected := tx.RowsAffected
		fmt.Println("insert log_api rows", affected)
	}(&insert2)

	wg.Wait()

}

// gorm.io/gorm blade_log_api 实现接口
func (api *Blade_log_api) BeforeCreate(tx *gorm.DB) (err error) {
	return err
}

func opt_query() {
	// find primary_key desc
	var log_api Blade_log_api
	tx := postgres_db.First(&log_api)
	if tx.Error != nil {
		fmt.Println("first log_api err", tx.Error)
	}
	marshal, _ := json.Marshal(log_api)
	fmt.Println(string(marshal))

	result := map[string]interface{}{}
	// Blade_log_api to map
	postgres_db.Table("ggzb.blade_log_api").Take(&result)

	bytes, _ := json.Marshal(result)

	fmt.Println(string(bytes))

	apis := []Blade_region{}
	// select all
	find := postgres_db.Find(&apis)
	fmt.Println("row is ", find.RowsAffected)

	//	i, _ := json.Marshal(apis)
	//	fmt.Println("json region is ", string(i))

	// 基于主键查询
	region := Blade_region{Code: "1305"}

	first := postgres_db.First(&region)
	row := first.Row()
	fmt.Println("region is ", region, " row is ", row)
}

func condition_query() {
	api := []Blade_log_api{}
	tx := postgres_db.Where("id < ?", 10).Find(&api)
	affected := tx.RowsAffected
	fmt.Println("query is ", api, "len is ", affected)
	// 使用同一个对象接收会被覆盖
	postgres_db.Where("id in ?", []int64{3496004945,
		3496004946,
		3496004947,
		3496004948,
		3496004949,
	}).Find(&api)

	rows, _ := postgres_db.Model(&Blade_log_api{}).Where("create_time between ? and ?",
		time.Now().Add(-10*time.Second), time.Now()).Rows()

	defer rows.Close()
	// 流式读取数据
	go func() {
		for rows.Next() {
			var api Blade_log_api
			postgres_db.ScanRows(rows, &api)
			fmt.Println("next read api ", api)
		}
	}()

	// 查询单列数据
	var ids []string
	postgres_db.Table("ggzb.blade_region").Pluck("code", &ids)

	fmt.Println("========", ids)
}

func exce_sql() {
	result := []map[string]interface{}{}

	tx := postgres_db.Raw("select * from ggzb.blade_user where status = ?", 1).Scan(&result)
	fmt.Println("rows length", tx.RowsAffected)

	// marshal, _ := json.Marshal(result)
	//fmt.Println("serialize json", string(marshal))

	var name []string
	var account []string
	// TODO Table name no find
	postgres_db.Table("ggzb.blade_user").Where("account = ?", "1001szrst222222").
		Select("account", "name").Row().Scan(&account, &name)

	fmt.Println("names :", name, "account :", account)

}

func belong_to_post_gress() {

}
